/*
 * $Id: CanDIActionResolver.java 6 2009-03-20 00:57:43Z scotthernandez $
 * $URL: https://condi-stripes.googlecode.com/svn/ConDI-Stripes/trunk/src/com/googlecode/condistripes/CanDIActionResolver.java $
 *
 * Copyright 2008-2009 Scott Hernandez
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

package com.googlecode.candistripes;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.controller.ActionBeanContextFactory;
import net.sourceforge.stripes.controller.ActionResolver;
import net.sourceforge.stripes.controller.NameBasedActionResolver;
import net.sourceforge.stripes.util.Log;

/**
 * An {@link ActionResolver} and {@link ActionBeanContextFactory} that creates (gets) classes from the (@link Manager)
 * This should be configured as params to the stripes servlet filter.
 * <pre>
 * 		<init-param>
 *	       <param-name>ActionResolver.Class</param-name>
 *	       <param-value>com.googlecode.candistripes.CanDIActionBeanHelper</param-value> 
 *    	</init-param>
 *		<init-param>
 *	       <param-name>ActionBeanContextFactory.Class</param-name>
 *	       <param-value>com.googlecode.candistripes.CanDIActionBeanHelper</param-value> 
 *    	</init-param>
 * </pre>
 * 
 * @author Scott Hernandez
 */
public class CanDIActionBeanHelper extends NameBasedActionResolver implements ActionBeanContextFactory {
	protected CanDIFactory[] facts = { 
				new ResinInjectorFactory(), 
				new JbossInjectorFactory(), 
				new OpenWebbeansInjectorFactory()
				};

	protected CanDIFactory fact = null;

    private Log log = Log.getInstance(CanDIActionBeanHelper.class);

    public CanDIActionBeanHelper() {
		log.debug("ctor: " + CanDIActionBeanHelper.class.toString());

		StringBuilder sb = new StringBuilder();

		if(fact == null) {
			for (CanDIFactory fact : facts) {
				if (fact.isAvailable()){
					log.debug("Using " + fact.getClass().getName());
					this.fact = fact;
					return;
				}

				sb.append(fact.toString()).append("\r\n");
			}
			String errMsg = "No jsr299 factories available:\r\n" + sb.toString();
			log.error(errMsg);
			throw new RuntimeException(errMsg);
		}
	}
	
	@Override
	protected ActionBean makeNewActionBean(Class<? extends ActionBean> type,
			ActionBeanContext context) throws Exception {
		
		log.debug("Using " + fact.getClass().getName() + " to get instance of " + type.toString());
		ActionBean ab = fact.getActionBean(type, context);
		log.debug("Retrieved class: " + ab.toString());
		
		return ab;
	}

	@Override
	public ActionBeanContext getContextInstance(HttpServletRequest req,
			HttpServletResponse res) throws ServletException {
		
		log.debug("Using " + fact.getClass().getName() + " to get instance of ActionBeanContext");
		ActionBeanContext abc = fact.getActionBeanContext();
		log.debug("Retrieved class: " + abc.getClass().getName());
		abc.setRequest(req);
		abc.setResponse(res);
		log.debug("Set HttpServletRequest/Response on " + abc.getClass().getName() + "#" + abc.hashCode());
		return abc;
	}
	
	/* Add when jsr299 RI is done.
	@Override
    protected Set<Class<? extends ActionBean>> findClasses() {
        Set<AbstractBean<? extends ActionBean>> filtBeans = ((InjectManager)mgr).resolve(ActionBean.class, null);
        
        for (AbstractBean<? extends ActionBean> bean : filtBeans)
        {
                ActionBean ab = (Class<? extends ActionBean>)bean.getTargetClass();
        }
		
	}
	*/
}